package edu.ccut.saturn.component.impl;

import java.util.List;

import edu.ccut.saturn.component.DefaultComponent;
import edu.ccut.saturn.component.IBaseComponentInfo;
import edu.ccut.saturn.component.IComponent;
import edu.ccut.saturn.component.IParameterInfo;
import edu.ccut.saturn.component.SaturnComponentException;
import edu.ccut.saturn.component.loader.ComponentLoader;
import edu.ccut.saturn.component.loader.node.NodeInfoLoader;
import edu.ccut.saturn.component.xml.ISaturnElement;
import edu.ccut.saturn.component.xml.SaturnElement;

/**
 * Base component information implementation
 * 
 * @see IBaseComponentInfo
 * @author LeslieGu
 */
public class SaturnBaseComponentInfo extends AbstractComponentInfo implements
		IBaseComponentInfo {

	private Class<?> className;

	private String bundleSymbolicName;

	public SaturnBaseComponentInfo() {
	}

	public SaturnBaseComponentInfo(String symbolicName, String key,
			String name, String description, Class<?> className,
			String bundleSymbolicName, List<IParameterInfo> parameterInfos,
			String loadStart) {

		super(symbolicName, key, name, description, parameterInfos, loadStart);
		this.className = className;
		this.bundleSymbolicName = bundleSymbolicName;
	}

	public Class<?> getClassType() {
		return className;
	}

	public void setClassName(Class<?> className) {
		this.className = className;
	}

	public IComponent createComponent() throws SaturnComponentException {
		Class<?> componentType = this.getClassType();

		IComponent component = null;

		try {
			component = (IComponent) componentType.newInstance();
			component.setComponentFullKey(this.getFullKey());

			if (component instanceof DefaultComponent) {
				DefaultComponent defaultComponent = (DefaultComponent) component;
				defaultComponent.setBundleSymbolicName(bundleSymbolicName);
				defaultComponent.setBaseComponentInfo(this);
			}
		} catch (Exception e) {
			throw new SaturnComponentException(e);
		}

		// logger.debug("create base component \"" + super.getFullKey() + "\"");
		return component;
	}

	public ISaturnElement toSaturnElement() {
		ISaturnElement saturnLogicElement = getRootElement();
		ISaturnElement componentElement = getComponentElement();
		saturnLogicElement.addSubElement(componentElement);
		return saturnLogicElement;
	}

	protected ISaturnElement getRootElement() {
		ISaturnElement saturnComponentElement = new SaturnElement(
				ComponentLoader.KEY_COMPONENT_ROOT);

		return saturnComponentElement;
	}

	protected ISaturnElement getComponentElement() {
		ISaturnElement componentElement = new SaturnElement(
				ComponentLoader.KEY_COMPONET);

		componentElement.addAttribute("key", this.getKey());
		componentElement.addAttribute("name", this.getName());
		componentElement.addAttribute("class", this.className.getName());

		ISaturnElement descriptionElement = new SaturnElement(
				ComponentLoader.KEY_MODULE_DESCRIPTION, this.getDescription());

		String loadstart = "false";
		
		if (this.getLoadStart() != null) {
			loadstart = this.getLoadStart();
		}

		ISaturnElement loadstartElement = new SaturnElement(
				ComponentLoader.KEY_COMPONENT_LOADSTART, loadstart);

		if (this.getParameterInfos() != null) {
			ISaturnElement parametersElement = new SaturnElement(
					NodeInfoLoader.KEY_PARAMETER_LIST);

			for (IParameterInfo parameterInfo : this.getParameterInfos()) {
				parametersElement
						.addSubElement(parameterInfo.toSaturnElement());
			}
			componentElement.addSubElement(parametersElement);
		}

		componentElement.addSubElement(descriptionElement);
		componentElement.addSubElement(loadstartElement);
		return componentElement;
	}
}
